import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Data, Router } from '@angular/router';
import {
  HttpMethod,
  Pageable,
  PageableResponse,
  SparrowUrl,
  Sysrole,
  SysroleUrlPermission,
  SysroleUrlPermissionPK,
  UrlPermissionEnum,
} from 'src/app/domain/sparrow';
import { UrlService } from 'src/app/service/url.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { BehaviorSubject, Observable, of, zip } from 'rxjs';
import { catchError, debounceTime, map, switchMap, tap } from 'rxjs/operators';
import {
  OpscopeService,
  PageableObject,
  ScopeApiPK,
  SparrowApi,
  SprapiService,
  SysroleService,
} from 'sparrow-permission-lib';
import { NzMessageService } from 'ng-zorro-antd/message';
import { ScopeSearchComponent } from 'src/app/share/scope-search/scope-search.component';

@Component({
  selector: 'app-url',
  templateUrl: './url.component.html',
  styleUrls: ['./url.component.css'],
})
export class UrlComponent implements OnInit {
  listOfData: SparrowUrl[] = [];
  httpMethods: any = [];
  urlPermissions: any = [];
  pageable: Pageable = { page: 1, size: 10, sort: ['createdDate,desc'] };
  total: number = 0;
  nzPage: number = 1; //阿里的分页从1开始

  constructor(
    private urlService: UrlService,
    private fb: FormBuilder,
    private apiService: SprapiService,
    private sysroleService: SysroleService,
    private message: NzMessageService,
    private scopeService: OpscopeService
  ) {
    this.httpMethods = Object.keys(HttpMethod);
    this.urlPermissions = Object.keys(UrlPermissionEnum);
  }

  getApis() {
    this.apiService
      .all7({
        page: this.pageable.page - 1,
        size: this.pageable.size,
        sort: this.pageable.sort,
      })
      .pipe(
        tap((res) => (this.total = res.totalElements!)),
        map((res) => res.content!),
        switchMap((apis: any[]) =>
          zip(
            ...apis.map((api) =>
              this.apiService.getScopes(api.id).pipe(
                switchMap((scopeApis: any[]) =>
                  scopeApis.length === 0
                    ? of([])
                    : zip(
                        ...scopeApis.map((scopeApi) =>
                          this.scopeService
                            .get5(scopeApi.id.scopeId)
                            .pipe(
                              map((scope) =>
                                Object.assign(scopeApi, { scope: scope })
                              )
                            )
                        )
                      )
                ),
                map((scopes) => Object.assign(api, { scopes: scopes }))
              )
            )
          )
        )
      )
      .subscribe((res: any) => {
        this.listOfCurrentPageData = res;
        // this.total = res.totalElements;
      });
  }

  validateForm!: FormGroup;
  ngOnInit(): void {
    this.getApis();
  }

  checked = false;
  loading = false;
  indeterminate = false;
  // listOfData: readonly Data[] = [];
  listOfCurrentPageData: readonly Data[] = [];
  setOfCheckedId = new Set<string>();

  updateCheckedSet(id: string, checked: boolean): void {
    if (checked) {
      this.setOfCheckedId.add(id);
    } else {
      this.setOfCheckedId.delete(id);
    }
  }

  onCurrentPageDataChange(listOfCurrentPageData: readonly Data[]): void {
    this.listOfCurrentPageData = listOfCurrentPageData;
    this.refreshCheckedStatus();
  }
  onPageIndexChange(page: number) {
    this.pageable.page = page;
    this.getApis();
  }

  onPageSizeChange(size: number) {
    this.pageable.size = size;
    this.getApis();
  }

  refreshCheckedStatus(): void {
    const listOfEnabledData = this.listOfCurrentPageData.filter(
      ({ disabled }) => !disabled
    );
    this.checked = listOfEnabledData.every(({ id }) =>
      this.setOfCheckedId.has(id)
    );
    this.indeterminate =
      listOfEnabledData.some(({ id }) => this.setOfCheckedId.has(id)) &&
      !this.checked;
  }

  onItemChecked(id: string, checked: boolean): void {
    this.updateCheckedSet(id, checked);
    this.refreshCheckedStatus();
  }

  onAllChecked(checked: boolean): void {
    this.listOfCurrentPageData
      // .filter(({ system }) => !system)
      .forEach(({ id }) => this.updateCheckedSet(id, checked));
    this.refreshCheckedStatus();
  }

  onDelete() {
    console.log(Array.from(this.setOfCheckedId));
    this.apiService
      .delete9(Array.from(this.setOfCheckedId))
      .subscribe((res) => {
        this.apiService.all7(this.pageable).subscribe((res) => {
          this.total = res.totalElements!;
          this.listOfCurrentPageData = res.content!;
          // this.listOfData = res.content;
        });
      });
    this.refreshCheckedStatus();
  }
  deleteApi(data: string) {
    this.apiService.delete9([data], 'response').subscribe((res) => {
      if (res.status === 204) this.getApis();
      else this.message.error('删除失败！' + res.body.error);
    });
  }

  isVisible = false;

  showModal(data: Data | null): void {
    let url: SparrowUrl;
    this.isVisible = true;
    if (data === null) {
      this.validateForm = this.fb.group({
        name: [null, [Validators.required]],
        uri: [null, [Validators.required]],
        method: [null, [Validators.required]],
        permission: [null, [Validators.required]],
        clientId: [null, [Validators.required]],
      });
    } else {
      this.validateForm = this.fb.group({
        name: [data.name, [Validators.required]],
        uri: [data.uri, [Validators.required]],
        method: [data.method, [Validators.required]],
        permission: [data.permission, [Validators.required]],
        clientId: [data.clientId, [Validators.required]],
        id: [data.id, [Validators.required]],
      });
    }
  }

  handleOk(): void {
    console.log('Button ok clicked!');
    // for (const i in this.validateForm.controls) {
    //   console.log(this.validateForm.value)
    // }
    this.isVisible = false;
    let url: SparrowUrl = this.validateForm.value;
    console.log(url);
    let urls: SparrowUrl[] = [];
    urls.push(this.validateForm.value);
    this.urlService.saveBatch(urls).subscribe((res) => {});
  }

  handleCancel(): void {
    console.log('Button cancel clicked!');
    this.isVisible = false;
  }

  // 新增或修改接口
  submitForm(): void {
    if (!this.validateForm.valid) {
      for (const i in this.validateForm.controls) {
        if (this.validateForm.controls.hasOwnProperty(i)) {
          this.validateForm.controls[i].markAsDirty();
          this.validateForm.controls[i].updateValueAndValidity();
        }
      }
    } else {
      let api: any = this.validateForm.value;
      api.isSystem = false;
      if (api.id === undefined) {
        this.apiService.create9(api).subscribe((res) => {
          this.isVisible = false;
        });
      } else {
        let uapi = { ...api };
        uapi.id = undefined;
        this.apiService.update10(api.id, uapi).subscribe((res) => {
          this.isVisible = false;
        });
      }
    }
  }

  onClose() {}

  handlePermissionCancel() {
    this.isVisibleForPermission = false;
  }

  // for permission
  optionList: any[] = [];
  selectedUser?: any[];
  isLoading = false;

  onSearch(value: string): void {
    this.isLoading = true;
    this.sysroleService
      .all({ page: 0, size: 100 }, value === '' ? undefined : { name: value })
      .subscribe((res) => {
        this.optionList = res.content!;
        this.isLoading = false;
      });
  }
  isVisibleForPermission = false;

  selectedUrls: SparrowUrl[] | any = [];
  setUrlPermission() {
    this.selectedUser = [];
    // // this.isVisibleForPermission = true;
    // // console.log(Array.from(this.setOfCheckedId))
    // this.selectedUrls = this.listOfCurrentPageData.filter((f) =>
    //   this.setOfCheckedId.has(f.id)
    // );

    // const getRandomNameList = (name: string) =>
    //   this.apiService.all6({ page: 0, size: 10 }).pipe(
    //     catchError(() => of({ results: [] })),
    //     map((res: any) => res.content)
    //   );
    // // .pipe(map((list: any) => list.map((item: any) => `${item.name}`)));
    // const optionList$: Observable<Sysrole[]> = this.searchChange$
    //   .asObservable()
    //   .pipe(debounceTime(500))
    //   .pipe(switchMap(getRandomNameList));
    // optionList$.subscribe((data) => {
    //   this.optionList = data;
    //   this.isLoading = false;
    // });
    // this.isVisibleForPermission = true;
  }

  selectedApi: any;
  showPermissionModal(api: any) {
    this.isVisibleForPermission = true;
    this.selectedApi = api;
    this.selectedUser = [];
  }
  addPermission() {
    this.apiService
      .addPermissions2(this.selectedApi.id, this.selectedUser!)
      .subscribe((res) => {
        this.isVisibleForPermission = false;
        this.onPageIndexChange(this.pageable.page - 1);
      });
  }

  @ViewChild(ScopeSearchComponent) scopeSearch!: ScopeSearchComponent;
  addScopes() {
    this.apiService
      .addScopes(
        this.selectedApi.id,
        this.scopeSearch.selectedUser!.map((scopes) => scopes.id),
        'response'
      )
      .subscribe((res) => {
        if (res.status === 204) {
          this.ngOnInit();
          this.isVisibleForPermission = false;
        }
      });
  }

  removeScopes(scopeApiId: ScopeApiPK, e: Event) {
    this.apiService
      .removeScopes(scopeApiId.apiId!, [scopeApiId.scopeId!], 'response')
      .subscribe((res) => {
        if (res.status != 204) {
          this.message.error('删除失败！');
        }
      });
  }

  delPermission() {
    let pks: SysroleUrlPermissionPK[] = [];
    this.selectedUrls.forEach((url: { id: any }) => {
      this.selectedUser?.forEach((user) => {
        let pk: SysroleUrlPermissionPK = new SysroleUrlPermissionPK();
        pk.sysroleId = user.id;
        pk.urlId = url.id;
        pks.push(pk);
      });
    });
    this.urlService.delPermission(pks).subscribe((res) => {
      this.isVisibleForPermission = false;
    });
  }

  currentPermissions: SysroleUrlPermission[] = [];

  isVisibleForCheckPermission: boolean = false;
  checkUrlPermission() {
    this.urlService
      .getPermissionById(Array.from(this.setOfCheckedId))
      .subscribe((res) => {
        this.currentPermissions = res.content;
        this.isVisibleForCheckPermission = true;
      });
  }

  handleCheckPermissionCancel() {
    this.isVisibleForCheckPermission = false;
  }

  onSysroleRemove(sysroleId: any, apiId: any, e: Event) {
    this.apiService
      .removePermissions2(apiId, [sysroleId], 'response')
      .subscribe((res) => {
        if (res.status === 204) {
          this.message.success('取消成功！');
        }
      });
  }
}
